package com.picshare.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.picshare.config.ServerConfig;
import com.picshare.model.FileItem;
import com.picshare.model.ShareLink;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
public class ShareService {
    
    @Value("${app.data.dir}")
    private String dataDir;
    
    @Value("${app.temp.dir}")
    private String tempDir;
    
    @Value("${app.share.expire-minutes:30}")
    private int expireMinutes;
    
    @Value("${app.share.max-downloads:10}")
    private int maxDownloads;
    
    private final ObjectMapper objectMapper = new ObjectMapper();
    private File shareFile;
    private List<ShareLink> shareLinks = new ArrayList<>();
    
    @PostConstruct
    public void init() {
        createDirectories();
        shareFile = new File(dataDir, "shares.json");
        loadShares();
        startCleanupTask();
    }
    
    private void createDirectories() {
        try {
            Files.createDirectories(Paths.get(dataDir));
            Files.createDirectories(Paths.get(tempDir));
        } catch (IOException e) {
            System.err.println("创建目录失败: " + e.getMessage());
        }
    }
    
    private void loadShares() {
        if (shareFile.exists()) {
            try {
                ShareLink[] shareArray = objectMapper.readValue(shareFile, ShareLink[].class);
                shareLinks = new ArrayList<>(Arrays.asList(shareArray));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    private void saveShares() {
        try {
            objectMapper.writerWithDefaultPrettyPrinter().writeValue(shareFile, shareLinks);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public ShareLink createShareLink(String fileId) {
        String token = UUID.randomUUID().toString();
        long now = System.currentTimeMillis();
        // 设置过期时间为很久以后（100年），相当于永久有效
        long expireTime = now + (100L * 365 * 24 * 60 * 60 * 1000L);
        
        ShareLink shareLink = new ShareLink();
        shareLink.setId(UUID.randomUUID().toString());
        shareLink.setFileId(fileId);
        shareLink.setToken(token);
        shareLink.setCreateTime(now);
        shareLink.setExpireTime(expireTime);
        shareLink.setDownloadCount(0);
        // 设置最大下载次数为很大的值，相当于无限制
        shareLink.setMaxDownloads(Integer.MAX_VALUE);
        shareLink.setBatch(false);
        
        shareLinks.add(shareLink);
        saveShares();
        
        return shareLink;
    }
    
    public ShareLink createBatchShareLink(List<String> fileIds) {
        String token = UUID.randomUUID().toString();
        long now = System.currentTimeMillis();
        // 设置过期时间为很久以后（100年），相当于永久有效
        long expireTime = now + (100L * 365 * 24 * 60 * 60 * 1000L);
        
        ShareLink shareLink = new ShareLink();
        shareLink.setId(UUID.randomUUID().toString());
        shareLink.setFileId(fileIds.get(0)); // 设置第一个文件ID作为主文件ID
        shareLink.setToken(token);
        shareLink.setCreateTime(now);
        shareLink.setExpireTime(expireTime);
        shareLink.setDownloadCount(0);
        // 设置最大下载次数为很大的值，相当于无限制
        shareLink.setMaxDownloads(Integer.MAX_VALUE);
        shareLink.setFileIds(fileIds);
        shareLink.setBatch(true);
        
        shareLinks.add(shareLink);
        saveShares();
        
        return shareLink;
    }
    
    public FileItem validateShare(String token) {
        return validateShare(token, false);
    }
    
    public FileItem validateShare(String token, boolean incrementDownload) {
        ShareLink shareLink = shareLinks.stream()
                .filter(s -> s.getToken().equals(token))
                .findFirst()
                .orElse(null);
        
        if (shareLink == null) {
            return null;
        }
        
        // 注释掉时间限制验证 - 分享链接永不过期
        // if (System.currentTimeMillis() > shareLink.getExpireTime()) {
        //     shareLinks.remove(shareLink);
        //     saveShares();
        //     return null;
        // }
        
        // 注释掉次数限制验证 - 分享链接无下载次数限制
        // if (shareLink.getDownloadCount() >= shareLink.getMaxDownloads()) {
        //     shareLinks.remove(shareLink);
        //     saveShares();
        //     return null;
        // }
        
        if (incrementDownload) {
            shareLink.setDownloadCount(shareLink.getDownloadCount() + 1);
            saveShares();
        }
        
        // 不再验证文件存在性，只返回一个基本的FileItem对象
        FileItem basicFileItem = new FileItem();
        basicFileItem.setId(shareLink.getFileId());
        basicFileItem.setFileName(""); // 文件名将在Controller中填充
        
        return basicFileItem;
    }
    
    public List<FileItem> validateBatchShare(String token, boolean incrementDownload) {
        ShareLink shareLink = shareLinks.stream()
                .filter(s -> s.getToken().equals(token))
                .findFirst()
                .orElse(null);
        
        if (shareLink == null || !shareLink.isBatch()) {
            return null;
        }
        
        // 注释掉时间限制验证 - 分享链接永不过期
        // if (System.currentTimeMillis() > shareLink.getExpireTime()) {
        //     shareLinks.remove(shareLink);
        //     saveShares();
        //     return null;
        // }
        
        // 注释掉次数限制验证 - 分享链接无下载次数限制
        // if (shareLink.getDownloadCount() >= shareLink.getMaxDownloads()) {
        //     shareLinks.remove(shareLink);
        //     saveShares();
        //     return null;
        // }
        
        if (incrementDownload) {
            shareLink.setDownloadCount(shareLink.getDownloadCount() + 1);
            saveShares();
        }
        
        return shareLink.getFileIds().stream()
                .map(fileId -> {
                    FileItem basicFileItem = new FileItem();
                    basicFileItem.setId(fileId);
                    basicFileItem.setFileName(""); // 文件名将在Controller中填充
                    return basicFileItem;
                })
                .collect(Collectors.toList());
    }
    
    public byte[] generateQRCode(String content) throws Exception {
        int width = 300;
        int height = 300;
        String format = "png";
        
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.MARGIN, 1);
        
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
        
        Path tempPath = Paths.get(tempDir, "qrcode_" + System.currentTimeMillis() + ".png");
        MatrixToImageWriter.writeToPath(bitMatrix, format, tempPath);
        
        byte[] qrCodeBytes = Files.readAllBytes(tempPath);
        Files.deleteIfExists(tempPath);
        
        return qrCodeBytes;
    }
    
    public String getShareUrl(String token) {
        ServerConfig serverConfig = ServerConfig.getInstance();
        return serverConfig.getServerUrl() + "/share/" + token;
    }
    
    // 移除FileService依赖以避免循环依赖
    // @Autowired
    // private FileService fileService;
    
    // 移除getFileItemById方法，因为不再需要验证文件存在性
    
    private void startCleanupTask() {
        // 注释掉定时清理任务 - 分享链接永不过期，不需要清理
        // scheduler.scheduleAtFixedRate(() -> {
        //     long now = System.currentTimeMillis();
        //     boolean removed = shareLinks.removeIf(s -> now > s.getExpireTime());
        //     if (removed) {
        //         saveShares();
        //     }
        // }, 5, 5, TimeUnit.MINUTES);
    }
    
    /**
     * 根据文件ID删除相关的所有分享记录
     * @param fileId 文件ID
     */
    public void deleteSharesByFileId(String fileId) {
        boolean removed = shareLinks.removeIf(s -> s.getFileId().equals(fileId) || 
                (s.getFileIds() != null && s.getFileIds().contains(fileId)));
        if (removed) {
            saveShares();
        }
    }
    
    /**
     * 根据文件ID列表删除相关的所有分享记录
     * @param fileIds 文件ID列表
     */
    public void deleteSharesByFileIds(List<String> fileIds) {
        boolean removed = shareLinks.removeIf(s -> {
            // 检查单个文件ID
            if (fileIds.contains(s.getFileId())) {
                return true;
            }
            // 检查批量分享中的文件ID列表
            if (s.getFileIds() != null) {
                return s.getFileIds().stream().anyMatch(fileIds::contains);
            }
            return false;
        });
        if (removed) {
            saveShares();
        }
    }
}